/*
    Copyright (C) 2011  Lucas Paradisi, FuDePAN


    This file is part of the FuDePAN's Discrete Molecular Dynamics Engine.


    FDMDE is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.


    FDMDE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.


    You should have received a copy of the GNU General Public License
    along with MiLi.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Mech2Dyn.h"
#include "fxp.h"

int Mech2Dyn::convert()
{

    bool ret;
    ParseErrorData ped;

    // Particle's position

    FXParserLOVMethod<Particle, void, Parameters3<Point, Point, Point> > positions("position", &Particle::setPosition);
    positions.parameters.set_param0("x");
    positions.parameters.set_param1("y");
    positions.parameters.set_param2("z");

    // Particle

    FXParserNonDef<Particle, Constructor2<Particle, Id, Id> > atom("particle");
    atom.constructor.set_param0("id");
    atom.constructor.set_param1("class");

    add_lov_child(atom, positions);


    // Class

    FXParserNonDef<Class, Constructor3<Class, Id, Mass, Diameter> > clasS("class");
    clasS.constructor.set_param0("id");
    clasS.constructor.set_param1("mass");
    clasS.constructor.set_param2("diameter");

    add_lov_child(clasS, string("color"), string("param"), &Class::colors);


    // Interaction's pairs

    FXParserLOVMethod<Interaction, void, Parameters2<const Id&, const Id&> > pairs("pair", &Interaction::addPair);
    pairs.parameters.set_param0("p1");
    pairs.parameters.set_param1("p2");

    // Interaction

    FXParserNonDef<Interaction, Constructor2<Interaction, Id, Id> > interaction("interaction");
    interaction.constructor.set_param0("id");
    interaction.constructor.set_param1("function");

    add_lov_child(interaction, string("param"), string("value"), &Interaction::parameters);
    add_lov_child(interaction, string("class"), string("id"), &Interaction::classes);
    add_lov_child(interaction, pairs);


    // Function

    FXParserLOVMethod<System, void, Parameters3<const Id&, Quantity, const std::string&> > function("function", &System::addFunction);
    function.parameters.set_param0("id");
    function.parameters.set_param1("parameters");
    function.parameters.set_param2("tags");


    // System

    FXPRootParser<System> Parser("system");
    add_child(Parser, &System::particles, atom);
    add_child(Parser, &System::interactions, interaction);
    add_child(Parser, &System::classes, clasS);
    add_lov_child(Parser, function);


    ignore_attr(Parser, "boundingboxlenght");
    ignore_attr(Parser, "energy");



    ret = parse_xml("../test.xml", data, Parser, ped, Warn, Warn);


    if (ret)
    {
        std::list<Particle>::iterator it1 = data.particles.begin();
        for (; it1 != data.particles.end(); it1++)
            std::cout << it1->id << " " << it1->fqn << " " << it1->x << " " << it1->y << " " << it1->z << std::endl;

        std::list<Interaction>::iterator it2 = data.interactions.begin();
        for (; it2 != data.interactions.end(); it2++)
            std::cout << it2->id << " " << it2->function << " " << it2->pairs.size() << " " << it2->parameters.size() << " " << it2->classes.size() << std::endl;


        std::list<Function>::iterator it3 = data.functions.begin();
        for (; it3 != data.functions.end(); it3++)
            std::cout << it3->id << " " << it3->numOfParameters << " " << it3->tags << std::endl;

        std::list<Class>::iterator it4 = data.classes.begin();
        for (; it4 != data.classes.end(); it4++)
            std::cout << it4->id << " " << it4->mass << " " << it4->diameter << " " << it4->colors.size() << std::endl;
    }
    else
    {    
        std::cerr << "Error: " << ped.error << " at line " << ped.line;
        return EXIT_FAILURE;
    }   

    return EXIT_SUCCESS;


}
